import sys
from PyQt6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QLabel, QLineEdit,
    QComboBox, QPushButton, QProgressBar, QMessageBox
)
from PyQt6.QtCore import Qt, QThread, pyqtSignal
import tftpy

class TFTPClientThread(QThread):
    progress = pyqtSignal(int)
    finished = pyqtSignal(bool)

    def __init__(self, server, filename, operation):
        super().__init__()
        self.server = server
        self.filename = filename
        self.operation = operation

    def run(self):
        try:
            client = tftpy.TftpClient(self.server, 69)
            if self.operation == 'Download':
                client.download(self.filename, self.filename, progresshook=self.progress_hook)
            else:
                client.upload(self.filename, self.filename, progresshook=self.progress_hook)
            self.finished.emit(True)
        except Exception as e:
            self.finished.emit(False)

    def progress_hook(self, pkt_size, progress, file_size):
        self.progress.emit(int(progress * 100 / file_size))

class TFTPClientUI(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        layout = QVBoxLayout()

        self.server_label = QLabel('TFTP Server Address:')
        self.server_input = QLineEdit()

        self.file_label = QLabel('File Path:')
        self.file_input = QLineEdit()

        self.operation_label = QLabel('Operation:')
        self.operation_input = QComboBox()
        self.operation_input.addItems(['Download', 'Upload'])

        self.start_button = QPushButton('Start')
        self.start_button.clicked.connect(self.start_operation)

        self.progress_bar = QProgressBar()
        self.progress_bar.setAlignment(Qt.AlignmentFlag.AlignCenter)

        layout.addWidget(self.server_label)
        layout.addWidget(self.server_input)
        layout.addWidget(self.file_label)
        layout.addWidget(self.file_input)
        layout.addWidget(self.operation_label)
        layout.addWidget(self.operation_input)
        layout.addWidget(self.start_button)
        layout.addWidget(self.progress_bar)

        self.setLayout(layout)
        self.setWindowTitle('TFTP Client')

    def start_operation(self):
        server = self.server_input.text()
        filename = self.file_input.text()
        operation = self.operation_input.currentText()

        if not server or not filename:
            QMessageBox.warning(self, 'Error', 'Please provide both server and file path.')
            return

        self.thread = TFTPClientThread(server, filename, operation)
        self.thread.progress.connect(self.update_progress)
        self.thread.finished.connect(self.operation_finished)
        self.thread.start()

    def update_progress(self, value):
        self.progress_bar.setValue(value)

    def operation_finished(self, success):
        if success:
            QMessageBox.information(self, 'Success', f'{self.operation_input.currentText()} completed successfully.')
        else:
            QMessageBox.warning(self, 'Failure', f'{self.operation_input.currentText()} failed.')
        self.progress_bar.setValue(0)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    client = TFTPClientUI()
    client.show()
    sys.exit(app.exec())
